package com.eduagent.xwqeduagent.controller;

import com.eduagent.xwqeduagent.api.imageTranslation.ImageTranslationClient;
import com.eduagent.xwqeduagent.api.imageTranslation.constant.ImageTranslationConstant;
import com.eduagent.xwqeduagent.api.imageTranslation.model.ImageInfo;
import com.eduagent.xwqeduagent.api.imageTranslation.model.ImageTranslationLanguage;
import com.eduagent.xwqeduagent.api.imageTranslation.model.ImageTranslationRequest;
import com.eduagent.xwqeduagent.model.dto.ImageTranslationDTO;
import com.eduagent.xwqeduagent.utils.CosUtils;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.Parameter;
import io.swagger.v3.oas.annotations.tags.Tag;
import jakarta.servlet.http.HttpServletRequest;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpStatus;
import org.springframework.http.MediaType;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;

import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.net.HttpURLConnection;
import java.net.URL;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.nio.file.StandardCopyOption;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.UUID;

/**
 * 图片翻译控制器
 */
@RestController
@RequestMapping("/image-translation")
@Tag(name = "图片翻译服务", description = "提供图片翻译功能，支持多种语言")
@Slf4j
public class ImageTranslationController {

    @Autowired
    private ImageTranslationClient imageTranslationClient;
    
    @Value("${edu.ai.document.tempDir}")
    private String tempDir;
    
    @Autowired
    private CosUtils cosUtils;
    
    /**
     * 上传并翻译图片
     *
     * @param file 要翻译的图片
     * @param from 源语言代码
     * @param to 目标语言代码
     * @param realmCode 领域代码（可选）：0-通用，1-医疗，2-专利
     * @return 包含文件编号的Map
     */
    @Operation(summary = "上传并翻译图片", description = "上传图片并开始异步翻译，支持PNG、JPG、JPEG、BMP等格式")
    @PostMapping("/upload")
    public Map<String, Object> uploadAndTranslate(
            @Parameter(description = "要翻译的图片文件") @RequestParam("file") MultipartFile file,
            @Parameter(description = "源语言代码，如zh(中文)、en(英文)等") @RequestParam String from,
            @Parameter(description = "目标语言代码，如zh(中文)、en(英文)等") @RequestParam String to,
            @Parameter(description = "领域代码（可选）：0-通用，1-医疗，2-专利") @RequestParam(required = false) Integer realmCode) {
        
        Map<String, Object> response = new HashMap<>();
        
        try {
            // 检查目录是否存在，不存在则创建
            Path tempPath = Paths.get(tempDir, "imageTranslation");
            if (!Files.exists(tempPath)) {
                Files.createDirectories(tempPath);
            }
            
            // 保存上传的文件到临时目录
            String originalFilename = file.getOriginalFilename();
            String tempFileName = UUID.randomUUID() + "_" + originalFilename;
            Path filePath = Paths.get(tempPath.toString(), tempFileName);
            file.transferTo(filePath.toFile());
            
            // 构建翻译请求
            ImageTranslationRequest request = ImageTranslationRequest.builder()
                    .from(from)
                    .to(to)
                    .file(filePath.toFile())
                    .realmCode(realmCode)
                    .build();
            
            // 上传并翻译文件
            String fileNo = imageTranslationClient.uploadAndTranslate(request);
            
            if (fileNo == null) {
                response.put("code", 500);
                response.put("msg", "图片翻译请求失败");
                response.put("data", null);
                return response;
            }
            
            // 构建成功响应
            response.put("code", 200);
            response.put("msg", "成功");
            
            Map<String, String> dataMap = new HashMap<>();
            dataMap.put("fileNo", fileNo);
            response.put("data", dataMap);
            
            return response;
        } catch (Exception e) {
            log.error("图片翻译异常: {}", e.getMessage(), e);
            response.put("code", 500);
            response.put("msg", "图片翻译异常: " + e.getMessage());
            response.put("data", null);
            return response;
        }
    }
    
    /**
     * 获取图片翻译进度
     *
     * @param fileNo 文件编号
     * @return 文档信息，包括翻译进度
     */
    @Operation(summary = "获取图片翻译进度", description = "根据文件编号查询翻译进度和状态")
    @GetMapping("/status/{fileNo}")
    public Map<String, Object> getStatus(
            @Parameter(description = "文件编号") @PathVariable String fileNo) {
        
        Map<String, Object> response = new HashMap<>();
        
        try {
            ImageInfo info = imageTranslationClient.getImageInfo(fileNo);
            
            if (info == null) {
                response.put("code", 404);
                response.put("msg", "未找到该任务或任务已过期");
                response.put("data", null);
                return response;
            }
            
            response.put("code", 200);
            response.put("msg", "成功");
            response.put("data", info);
            return response;
        } catch (Exception e) {
            log.error("获取图片翻译状态异常: {}", e.getMessage(), e);
            response.put("code", 500);
            response.put("msg", "获取图片翻译状态异常: " + e.getMessage());
            response.put("data", null);
            return response;
        }
    }
    
    /**
     * 获取翻译文件下载链接
     *
     * @param fileNo 文件编号
     * @param type 下载类型（可选）：0-原图，1-译图（默认），2-双语图
     * @return 文件COS链接
     */
    @Operation(summary = "获取翻译文件COS链接", description = "获取翻译文件的COS存储链接")
    @GetMapping("/download-url/{fileNo}")
    public Map<String, Object> getDownloadUrl(
            @Parameter(description = "文件编号") @PathVariable String fileNo,
            @Parameter(description = "下载类型（可选）：0-原图，1-译图（默认），2-双语图") 
            @RequestParam(required = false, defaultValue = "1") Integer type) {
        
        Map<String, Object> response = new HashMap<>();
        
        try {
            // 获取原始下载链接
            String originalUrl = imageTranslationClient.getDownloadUrl(fileNo, type);
            
            if (originalUrl == null || originalUrl.isEmpty()) {
                response.put("code", 404);
                response.put("msg", "未找到该任务或任务已过期");
                response.put("data", null);
                return response;
            }
            
            // 获取图片信息
            ImageInfo info = imageTranslationClient.getImageInfo(fileNo);
            String fileName = info != null ? info.getFileName() : fileNo + "_" + type + ".png";
            
            // 创建临时文件
            Path tempPath = Paths.get(tempDir, "imageTranslation");
            if (!Files.exists(tempPath)) {
                Files.createDirectories(tempPath);
            }
            String tempFileName = UUID.randomUUID() + "_" + fileName;
            Path tempFilePath = Paths.get(tempPath.toString(), tempFileName);
            File tempFile = tempFilePath.toFile();
            
            // 下载文件到本地
            URL url = new URL(originalUrl);
            HttpURLConnection connection = (HttpURLConnection) url.openConnection();
            connection.setRequestMethod("GET");
            
            // 确保跟随重定向
            connection.setInstanceFollowRedirects(true);
            
            // 获取内容类型
            String contentType = connection.getContentType();
            log.info("下载图片的内容类型: {}", contentType);
            
            // 获取文件大小
            int contentLength = connection.getContentLength();
            
            try (InputStream inputStream = connection.getInputStream()) {
                Files.copy(inputStream, tempFilePath, StandardCopyOption.REPLACE_EXISTING);
            }
            
            // 上传到COS，确保传递正确的内容类型
            String cosUrl;
            if (contentType != null && !contentType.isEmpty()) {
                // 如果有内容类型，使用带内容类型的上传方法
                try (InputStream fileInputStream = Files.newInputStream(tempFilePath)) {
                    cosUrl = cosUtils.uploadFile(fileInputStream, fileName, contentType, "image-translation", tempFile.length());
                }
            } else {
                // 否则使用文件上传
                cosUrl = cosUtils.uploadFile(tempFile, "image-translation");
            }
            
            // 删除临时文件
            Files.deleteIfExists(tempFilePath);
            
            response.put("code", 200);
            response.put("msg", "成功");
            response.put("data", cosUrl);
            return response;
        } catch (Exception e) {
            log.error("处理翻译图片异常: {}", e.getMessage(), e);
            response.put("code", 500);
            response.put("msg", "处理翻译图片异常: " + e.getMessage());
            response.put("data", null);
            return response;
        }
    }
    
    /**
     * 下载翻译后的图片
     *
     * @param fileNo 文件编号
     * @param type 下载类型（可选）：0-原图，1-译图（默认），2-双语图
     * @return 重定向到下载链接
     */
    @Operation(summary = "下载翻译后的图片", description = "下载翻译结果图片")
    @GetMapping("/download/{fileNo}")
    public ResponseEntity<?> downloadImage(
            @Parameter(description = "文件编号") @PathVariable String fileNo,
            @Parameter(description = "下载类型（可选）：0-原图，1-译图（默认），2-双语图") 
            @RequestParam(required = false, defaultValue = "1") Integer type) {
        
        try {
            // 获取下载链接
            String downloadUrl = imageTranslationClient.getDownloadUrl(fileNo, type);
            
            if (downloadUrl == null || downloadUrl.isEmpty()) {
                return ResponseEntity.notFound().build();
            }
            
            // 获取图片信息
            ImageInfo info = imageTranslationClient.getImageInfo(fileNo);
            if (info == null) {
                return ResponseEntity.notFound().build();
            }
            
            // 检查翻译状态
            if (info.getTransStatus() != ImageTranslationConstant.TranslationStatus.SUCCESS) {
                return ResponseEntity.badRequest().body("翻译尚未完成，当前状态: " + info.getTransStatus());
            }
            
            // 重定向到下载链接
            return ResponseEntity.status(302)
                    .header(HttpHeaders.LOCATION, downloadUrl)
                    .build();
        } catch (Exception e) {
            log.error("下载图片异常: {}", e.getMessage(), e);
            return ResponseEntity.status(500).body("下载图片异常: " + e.getMessage());
        }
    }
    
    /**
     * 中断图片翻译任务
     *
     * @param fileNo 文件编号
     * @return 操作结果
     */
    @Operation(summary = "中断图片翻译任务", description = "中断正在进行的图片翻译任务")
    @PostMapping("/interrupt/{fileNo}")
    public Map<String, Object> interruptTranslation(
            @Parameter(description = "文件编号") @PathVariable String fileNo) {
        
        Map<String, Object> response = new HashMap<>();
        
        try {
            boolean success = imageTranslationClient.interruptTranslation(fileNo);
            
            response.put("code", 200);
            response.put("msg", "成功");
            response.put("data", success);
            
            return response;
        } catch (Exception e) {
            log.error("中断图片翻译任务异常: {}", e.getMessage(), e);
            response.put("code", 500);
            response.put("msg", "中断图片翻译任务异常: " + e.getMessage());
            response.put("data", false);
            return response;
        }
    }
    
    /**
     * 删除图片翻译任务
     *
     * @param fileNo 文件编号
     * @return 操作结果
     */
    @Operation(summary = "删除图片翻译任务", description = "删除图片翻译任务及相关文件")
    @DeleteMapping("/{fileNo}")
    public Map<String, Object> deleteTranslation(
            @Parameter(description = "文件编号") @PathVariable String fileNo) {
        
        Map<String, Object> response = new HashMap<>();
        
        try {
            boolean success = imageTranslationClient.deleteImage(fileNo);
            
            response.put("code", 200);
            response.put("msg", "成功");
            response.put("data", success);
            
            return response;
        } catch (Exception e) {
            log.error("删除图片翻译任务异常: {}", e.getMessage(), e);
            response.put("code", 500);
            response.put("msg", "删除图片翻译任务异常: " + e.getMessage());
            response.put("data", false);
            return response;
        }
    }
    
    /**
     * 同步翻译图片（直接返回结果）
     *
     * @param file 要翻译的图片
     * @param from 源语言代码
     * @param to 目标语言代码
     * @param base64 图片base64编码（与文件二选一）
     * @param resultType 结果类型：0-文件流（默认），1-base64编码
     * @param realmCode 领域代码（可选）：0-通用，1-医疗，2-专利
     * @return 翻译结果
     */
    @Operation(summary = "同步翻译图片", description = "直接翻译图片并返回结果，无需查询状态")
    @PostMapping("/translate-sync")
    public ResponseEntity<?> translateSync(
            @Parameter(description = "要翻译的图片文件") @RequestParam(required = false) MultipartFile file,
            @Parameter(description = "源语言代码，如zh(中文)、en(英文)等") @RequestParam String from,
            @Parameter(description = "目标语言代码，如zh(中文)、en(英文)等") @RequestParam String to,
            @Parameter(description = "图片base64编码，与文件二选一") @RequestParam(required = false) String base64,
            @Parameter(description = "结果类型：0-文件流（默认），1-base64编码") @RequestParam(required = false, defaultValue = "0") Integer resultType,
            @Parameter(description = "领域代码（可选）：0-通用，1-医疗，2-专利") @RequestParam(required = false) Integer realmCode) {
        
        try {
            if ((file == null || file.isEmpty()) && (base64 == null || base64.isEmpty())) {
                return ResponseEntity.badRequest().body("必须提供图片文件或base64编码");
            }
            
            File tempFile = null;
            if (file != null && !file.isEmpty()) {
                // 保存上传的文件到临时目录
                Path tempPath = Paths.get(tempDir, "imageTranslation");
                if (!Files.exists(tempPath)) {
                    Files.createDirectories(tempPath);
                }
                
                String originalFilename = file.getOriginalFilename();
                String tempFileName = UUID.randomUUID() + "_" + originalFilename;
                Path filePath = Paths.get(tempPath.toString(), tempFileName);
                file.transferTo(filePath.toFile());
                tempFile = filePath.toFile();
            }
            
            // 构建翻译请求
            ImageTranslationRequest request = ImageTranslationRequest.builder()
                    .from(from)
                    .to(to)
                    .file(tempFile)
                    .base64(base64)
                    .resultType(resultType)
                    .realmCode(realmCode)
                    .build();
            
            // 同步翻译图片
            Object result = imageTranslationClient.translateImageSync(request);
            
            if (result == null) {
                return ResponseEntity.status(500).body("图片翻译失败");
            }
            
            // 根据结果类型返回不同格式
            if (resultType != null && resultType == ImageTranslationConstant.ResultType.BASE64) {
                // 返回base64字符串
                Map<String, Object> response = new HashMap<>();
                response.put("code", 200);
                response.put("msg", "成功");
                response.put("data", result);
                return ResponseEntity.ok(response);
            } else {
                // 返回文件流
                return ResponseEntity.ok()
                        .contentType(MediaType.IMAGE_PNG)
                        .body(result);
            }
        } catch (Exception e) {
            log.error("同步翻译图片异常: {}", e.getMessage(), e);
            Map<String, Object> response = new HashMap<>();
            response.put("code", 500);
            response.put("msg", "同步翻译图片异常: " + e.getMessage());
            response.put("data", null);
            return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR).body(response);
        }
    }
    
    /**
     * 获取支持的语言列表
     *
     * @return 支持的语言列表
     */
    @Operation(summary = "获取支持的语言列表", description = "获取图片翻译支持的语言列表及代码")
    @GetMapping("/languages")
    public Map<String, Object> getSupportedLanguages() {
        Map<String, Object> response = new HashMap<>();
        List<Map<String, String>> languages = new ArrayList<>();
        
        for (ImageTranslationLanguage lang : ImageTranslationLanguage.values()) {
            Map<String, String> langMap = new HashMap<>();
            langMap.put("code", lang.name());
            langMap.put("langCode", lang.getCode());
            langMap.put("name", lang.getDisplayName());
            languages.add(langMap);
        }
        
        response.put("code", 200);
        response.put("msg", "成功");
        response.put("data", languages);
        
        return response;
    }
} 